import os
import time
import uuid
import ast
from utilsapp import utils
from flask import Blueprint, request, jsonify, current_app,send_from_directory, send_file,render_template
from collections import defaultdict
from utilsapp.mysql_con import  db_delete, db_insert,db_list
from utilsapp.mysql_con import db_pagelist, db_fetchone , db_connect,db_deletes,db_fetchall
from utilsapp.makeport import create_port
from utilsapp.common import assign_value, parsing_data_id, parsing_permissions
from datetime import datetime
report = Blueprint('report', __name__)


# 查询诊断报告
@report.route('/getlist', methods=['POST'])
def a():
    a = request.json
    scope_id = assign_value(a, "scope_id", 0)
    scoped = parsing_data_id(scope_id, request)
    title = assign_value(a, "title")
    maker = assign_value(a, "maker")
    start_time = assign_value(a, "start_time")
    end_time = assign_value(a, "end_time")
    status = assign_value(a, "status")
    type_ = assign_value(a,"type")
    query = ""
    if scoped != "":
        query += f" and {scoped}"
    if maker != "":
        query += f" and maker like '%{maker}%'"
    if title != "":
        query += f" and title like '%{title}%'"
    if start_time != "":
        query += f" and create_time > {start_time}"
    if end_time != "":
        query += f" and create_time < {end_time}"
    if status != "":
        query += f" and status = {status}"
    if type_ != "":
        query += f" and type = {type_}"
    elif type_ =='':
        query += f" and type != 3"
    sql = f"select * from report where 1=1 {query} ORDER BY create_time desc"

    sql_1 = f"select count(id) from report where 1=1 {query} and status="
    res = db_pagelist(sql, a['page'])
    res1 = db_fetchone(sql_1 + '1')
    res0 = db_fetchone(sql_1 + '0')
    res['stat'] = {
        "editing": res0['data'],
        "completed": res1['data']
    }
    return res


@report.route('/upload', methods=['POST','get'])
def upload():
    try:
        # 检查请求中是否包含文件
        if 'file' not in request.files:
            return jsonify({'code': -1, 'msg': '空文件'}), 200
        dimg = request.args.get('dimg')
        file = request.files['file']
        # 检查文件是否为空
        if file.filename == '':
            return jsonify({'code': -1, 'msg': '空文件'}), 200
        script_dir = os.path.dirname(os.path.abspath(__name__)) + '/static'
        date = time.strftime("%Y%m%d", time.localtime())
        ext = os.path.splitext(file.filename)[-1]
        fileName = f'/upload/{date}'
        filePath = script_dir + fileName
        if not os.path.exists(filePath):
            os.mkdir(filePath)
        fileName = f'/upload/{date}/{uuid.uuid1()}{ext}'

        filePath = script_dir + fileName

        ALLOWED_EXTENSIONS = {'pdf', 'png', 'jpg', 'jpeg', 'gif','txt'}
        if ('.' in file.filename and file.filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS) == False:
            return jsonify({'code': -1, 'msg': '上传失败,非法文件类型'}), 200
        if ext == '.pdf':
            filePath = script_dir + f'/upload/{file.filename}'
            fileName = file.filename
        if dimg=='1':

            filePath = script_dir + '/upload/dimg'
            if not os.path.exists(filePath):
                os.mkdir(filePath)
            filePath =filePath+'/'+ file.filename
            fileName = '/upload/dimg/'+file.filename
        # 保存文件到指定目录
        print("上传路径",filePath , fileName)
        file.save(filePath)
        return jsonify({'code': 0, 'msg': '上传成功', 'data': fileName}), 200
    except Exception as e:
        return jsonify({'code': -1, 'msg': '上传异常'}), 200


@report.route('/add', methods=['post'])
def add():
    return db_insert('report', request.json)


@report.route('/viewpdf/<path:filename>', methods=['POST', 'GET'])
def view_file(filename):
    try:
        script_dir = os.path.dirname(os.path.abspath(__name__)) + '/static'
        filePath = script_dir + '/upload/'+ filename
        print("下载路径",filePath)
        return send_file(filePath, mimetype='application/pdf')
    except Exception as e:

        return jsonify({'code': -1, 'msg': '下载异常'+str(e)}), 200


@report.route('/download/<path:filename>', methods=['POST', 'GET'])
def download_file(filename):
    try:
        script_dir = os.path.dirname(os.path.abspath(__file__))
        filePath = script_dir + '/upload/'

        return send_from_directory(filePath, filename, as_attachment=True)
    except Exception as e:
        return jsonify({'code': -1, 'msg': '下载异常'}), 200


@report.route('delete', methods=['post'])
def report_delete():
    id_ = request.json['id']
    return db_delete("report", f"where id = %s", {'mid': id_})

@report.route('deletes', methods=['post'])
def report_deletes():
    id_ = ' or '.join([('id = ' + str(item)) for item in request.json['idList']])
    sql = f"DELETE FROM report where {id_}"

    return db_deletes(sql)





def convert_tuple(lst):
    if len(lst) == 1:
        return f"({lst[0]})"
    else:
        return tuple(lst)


def get_page1(device_ids, times, group_name):
    return  {
        "title": "设备状态监测分析报告",
        "times": times,
        "project_name": group_name,
        "company":"XXXXXXX有限公司",
        "reporter": "系统生成",
        "examine": "审核人",
        "permiss": "批准人",
        "create_time": datetime.now().strftime("%Y年%m月%d日")
    }



def set_result(results, a):
    result_list = []
    for pair in a:
        i, j = pair
        if i != 0 and j != 0:
            result_list.append(results[i][j])
    if not result_list:
        result_list.append('正常')
    # 使用set去重，并转换为列表
    result_list = list(set(result_list))
    return ','.join(result_list)


def setList(input_str):
    if input_str == "[]":
        input_str = "[0, 0]"

    input_str = input_str.replace('[','').replace(']','').split(',')
    # 安全地解析输入字符串
    processed_lst = [0,0]
        # 定义映射字典
    replacement_map = {
        "固定阈值": 1,
        "动态阈值": 2,
        "趋势预测": 3,
        "机理模型": 4,
        "AI模型": 5,
    }

    try:
        processed_lst[0]=int(input_str[0])
    except:
        processed_lst[0]=replacement_map[input_str[0]]
    processed_lst[1]= int(input_str[1])

    return [tuple(processed_lst)]


def get_page3s(device_ids,times,type_=0):
    page_len1 = 20
    stime = times[0]
    etime = times[1]
    titles = ['一、诊断总结，状态描述和维护建议','一、报警设备状态']
    results = [
    ['正常' ,'正常','正常','正常'],
    [ '正常','固定阈值轻微超限', '固定阈值中等超限', '固定阈值严重超限'],
    [ '正常','动态阈值轻微超限', '动态阈值中等超限', '动态阈值严重超限'],
    [ '正常','特征趋势轻微超限', '特征趋势中等超限', '特征趋势严重超限'],
    [ '正常','智能告警轻微告警', '智能告警中等告警', '智能告警严重告警'],
    [ '正常','机理告警轻微告警', '机理告警中等告警', '机理告警严重告警']
]
    suggests = [
        "设备正常",
        "按计划维护，关注运行数据",
        "关注趋势，对比历史数据排查",
        "分析数据，现场检查，适时调整"
    ]
    status_ = ["正常","一般告警","中等告警","严重告警"]
    sql2 = ''
    if type_==0:
        sql2 = f'''
        SELECT
    d.device_name,
    COALESCE(MAX(w.warn_level), 0) AS warn_level,
    IFNULL(GROUP_CONCAT(CONCAT('[', w.warn_source, ',', w.warn_level, ']')), '[]') AS result_list
FROM
    device d
LEFT JOIN (
    SELECT
        device_id,
        warn_source,
        MAX(warn_level) AS warn_level
    FROM
        warn
    WHERE
        is_show = 1 
        AND notice NOT IN (3,4) 
        AND pred_time BETWEEN '{stime}' AND '{etime}'
    GROUP BY
        device_id,
        warn_source
) w ON w.device_id = d.id
WHERE
    d.id IN {convert_tuple(device_ids)}
GROUP BY
    d.device_name;
        '''
    elif type_ ==1:
        sql2 = f'''
SELECT 
    d.device_name,
    s.sensor_name,
    COALESCE(MAX(w.warn_level), 0) AS warn_level,
    IFNULL( GROUP_CONCAT(CONCAT('[', w.warn_source, ',', w.warn_level, ']')),'[0,0]') AS result_list
FROM 
    sensor s
JOIN 
    device d ON d.id = s.device_id
LEFT JOIN (
    SELECT 
        * 
    FROM 
        warn
    WHERE 
        is_show = 1 AND 
        notice NOT IN (3,4) and pred_time between '{stime}' and '{etime}'
) w ON w.sensor_id = s.id
WHERE 
    d.id = {device_ids[0]}
GROUP BY 
    d.device_name,
    s.sensor_name
ORDER BY 
    d.device_name,
    s.sensor_name,
    MAX(w.warn_level) DESC;
'''
    items = db_list(sql2)['data']
    if type_ == 0 :
        page3s = [{
            "title": titles[type_],
            "list": [],
        }]
        for index, item in enumerate(items):
            device_dict = {
                "device_name": item['device_name'],
                "status": status_[item["warn_level"]],
                "result": set_result(results,setList( item['result_list'])),
                "suggest": suggests[item["warn_level"]],
            }
            current_page = page3s[-1]
            current_page_list = current_page["list"]
            current_page_list.append(device_dict)
            if len(current_page_list) == page_len1 and index  < len(items)-1:
                new_page = {
                    "title": titles[type_],
                    "list": []
                }
                page3s.append(new_page)
    elif type_ ==1:
        page3s = [{
            "title": titles[type_],
            "list": [],
            "device_name":items[0]['device_name']
        }]
        for index, item in enumerate(items):
            device_dict = {
                "sensor_name": item['sensor_name'],
                "status": status_[item["warn_level"]],
                "result": set_result(results,setList( item['result_list'])),
                 "suggest": suggests[item["warn_level"]],
            }
            current_page = page3s[-1]
            current_page_list = current_page["list"]
            current_page_list.append(device_dict)
            if len(current_page_list) == page_len1 and index  < len(items)-1:
                new_page = {
                    "title": titles[type_],
                    "list": [],
                    "device_name":items[0]['device_name']
                }
                page3s.append(new_page)
    return page3s



def timesFor(date_string):

    date_format = "%Y-%m-%d %H:%M:%S"
# 将日期时间字符串转换为 datetime 对象
    dt = datetime.strptime(date_string, date_format)
# 获取对应的时间戳（10位）
    timestamp = int(dt.timestamp())
    return timestamp


def get_channel(address):
    parts = address.split('_')
    first_number = str(parts[0])
    second_number = str(parts[1]) if len(parts) > 1 else '0'
    return [first_number, second_number]


def dilute_list(lst):
    if len(lst) > 10000:
        ratio = len(lst) / 10000
        new_lst = [lst[int(i * ratio)] for i in range(10000)]
        return new_lst
    else:
        return lst


def get_page4s(device_ids,times,pagesize=4):
    page_len1 = pagesize
    stime = times[0]
    etime = times[1]
    warn_level_dir = [ "正常","一般告警","中等告警","严重告警"]
    sql1 = f'''SELECT s.sensor_name,IFNULL( MAX(w.warn_level),0) as warn_level,d.device_name,s.address,s.port,st.single,s.direction,
                r.proj_no
				from sensor s
				LEFT JOIN ( SELECT * from warn where is_show = 1 AND notice not in (3,4) and pred_time between '{stime}' and '{etime}' ) w on w.sensor_id = s.id
				LEFT JOIN device d on d.id = s.device_id
                left join sensor_type st on st.id = s.sensor_type
                LEFT JOIN regionlevel r on r.id = d.group_id
					where d.id in {convert_tuple(device_ids)}
				GROUP BY s.id'''
    items = db_list(sql1)['data']
    page4s = [{
        "title": "二、设备振动趋势分析",
        "list": [],
    }]
    for index, item in enumerate(items):
        device_name = item['device_name']
        sensor_name = item['sensor_name']
        address = item['address']
        port = item['port']
        warn_level = item['warn_level']
        sport = port
        arr=get_channel(address)
        saddr = arr[0]
        channel = arr[1]
        proj_no = item['proj_no']
        mgdb = current_app.mgdb[f'ieplat_{proj_no}']
        collection = mgdb[f"eige"]
        query = {
        "$and": [
            {"_id": {"$gte": f'{sport}_{saddr}_{channel}_{timesFor(stime)}'}},
            {"_id": {"$lte": f'{sport}_{saddr}_{channel}_{timesFor(etime)}'}}
        ]
    }
        projection = {"_id": 1, **{f"data.{e}": 1 for e in ['Z.vel_rms','Z.acc_rms']}}
    # 执行查询
        result = collection.find(query, projection)
        d = [{"id": t["_id"][-10:], **t["data"]} for t in result]
        current_page = page4s[-1]
        current_page_list = current_page["list"]
        current_page_list.append({
            "device_name":device_name,
            "sensor_name":sensor_name,
            "status":warn_level_dir[warn_level],
            "data":dilute_list(d),
            "number":f'{port}_{address}'
        })
        if len(current_page_list) == page_len1 and index  < len(items)-1:
            page4s.append({
                "title": "二、设备振动趋势分析",
                "list": []
            })
    return page4s


@report.route('down/sys', methods=['post'])
def a23321():
    a = request.json
    device_ids = assign_value(a, "device_ids", [])
    times = assign_value(a, "times", [])
    type_ = assign_value(a,'type_',0)
    sql = f'''select r.name from device d
        LEFT JOIN regionlevel r on r.id = d.group_id
        where d.id = {device_ids[0]} '''
    times1 = [convert_date(times[0]), convert_date(times[1])]
    group_name = db_fetchone(sql)['data']
    page1 = get_page1(device_ids, times1, group_name)
    page3s = get_page3s(device_ids , times,type_)
    page4s = get_page4s(device_ids , times)
    a = create_port(page1,page3s,page4s,type_)
    
    if type_ ==0:
        return send_file(a[0], as_attachment=True, attachment_filename=a[1]+'.pdf')
    elif type_ ==1:
        return save_warn_port(a[0],a[1],device_ids[0])
        

def save_warn_port(filepath,filename,device_id):

    sql = '''SELECT d.zone_id ,z.name as zone_name ,d.factory_id,f.name as factory_name,
d.company_id,d.group_id,c.name as company_name,g.name as group_name ,g.proj_no
FROM device d
left JOIN regionlevel z on z.id = d.zone_id
LEFT JOIN regionlevel f on f.id = d.factory_id
LEFT JOIN regionlevel c on c.id = d.company_id
LEFT JOIN regionlevel g on g.id = d.group_id
WHERE d.id = '''
    zone_id , zone_name,factory_id,factory_name,company_id,group_id,company_name,group_name,proj_no=  db_fetchall(f"{sql}{device_id}")['data'][0]
    return db_insert('report',{
        "title":filename,
        "maker":"系统生成",
        "result":"pdf文件内查看",
        "status":1,
        "device_id":device_id,
        "zone_id":zone_id,
        "factory_id":factory_id,
        "company_id":company_id,
        "group_id":group_id,
        "filepath":filename + '.pdf',
        "type":2
    })


def convert_date(input_date):
    # 将字符串转换为 datetime 对象
    date_obj = datetime.strptime(input_date, "%Y-%m-%d %H:%M:%S")
    # 格式化为指定的日期字符串
    formatted_date = date_obj.strftime("%Y年%m月%d日")
    return formatted_date



def categorize_data(input_list):
    output_dict = defaultdict(list)
    for item in input_list:
        feature_key = item['feature_key']
        time = item['time']
        value = item['value']
        feature_key = feature_key[1:]
        output_dict[feature_key].append({'time': time, 'value': value})
    return dict(output_dict)



def reduce_list_length(lst, target_length=8000):
    if len(lst) <= target_length:
        return lst
    # 确定步长
    step = len(lst) // target_length
    # 进行稀释
    new_lst = [lst[i] for i in range(0, len(lst), step)]
    return new_lst



    

    